﻿using DevComponents.DotNetBar;
using SharpErp.UI.Common;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using SharpErp.UI.Common.Attribute;

namespace SharpErp
{
    public partial class MainForm : DevComponents.DotNetBar.RibbonForm
    {

        private readonly Dictionary<string, Tuple<MenuAttribute, Type>> _mapName2FormTypes = new Dictionary<string, Tuple<MenuAttribute, Type>>();
        private readonly Dictionary<MenuModule, ButtonItem> _menuModule2ButtonItem = new Dictionary<MenuModule, ButtonItem>();
        private Command _appCommandTheme;

        public MainForm()
        {
            BeforeAllControlLoad();
            InitializeComponent();
            this.IsMdiContainer = true;
            AfterAllControlLoad();
        }

        private void BeforeAllControlLoad()
        {
            
        }

        private void AfterAllControlLoad()
        {

            foreach (var item in mainRibbonControl.Items)
            {
                var buttonItem = item as ButtonItem;
                if(string.IsNullOrEmpty(buttonItem?.CommandParameter?.ToString())) continue;
                _menuModule2ButtonItem[(MenuModule) Enum.Parse(typeof(MenuModule), buttonItem.CommandParameter.ToString(), true)] = buttonItem;
            }
       
            // 
            // bubbleBar1
            // 
            this.bubbleBar1.AntiAlias = true;
            this.bubbleBar1.BackColor = System.Drawing.Color.Transparent;
            // 
            // bubbleBar1.ButtonBackAreaStyle
            // 
     
            this.bubbleBar1.MouseOverTabColors.BorderColor = System.Drawing.SystemColors.Highlight;
            this.bubbleBar1.Name = "bubbleBar1";
            this.bubbleBar1.SelectedTab = this.bubbleBarTab1;
            this.bubbleBar1.Size = new System.Drawing.Size(488, 52);
            this.bubbleBar1.TabIndex = 0;
            this.bubbleBar1.Tabs.Add(this.bubbleBarTab1);
            this.bubbleBar1.Text = "";
            this.bubbleBar1.TooltipFont = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            this.panelEx1.Controls.Add(this.bubbleBar1);
           

            // Apply UI changes and refresh
            bubbleBar1.Dock = System.Windows.Forms.DockStyle.Bottom;
            bubbleBar1.ButtonBackgroundStretch = false;
            bubbleBar1.Width = bubbleBar1.ImageSizeNormal.Width*(bubbleBarTab1.Buttons.Count) + 20;
            bubbleBar1.RecalcLayout();
            bubbleBar1.Refresh();

            // 
            // AppCommandTheme
            // 
            // 
            this._appCommandTheme = new Command {Name = "AppCommandTheme"};
            this._appCommandTheme.Executed += new System.EventHandler(Target);

            //button style.
            foreach (var item in buttonChangeStyle.SubItems)
            {
                if (item is ButtonItem && ((ButtonItem)item).Name.StartsWith("buttonStyle"))
                {
                    ((ButtonItem) item).Command = _appCommandTheme;
                }
            }
            this.buttonStyleCustom.Command = _appCommandTheme;
        }

        private void Target(object sender, EventArgs eventArgs)
        {
            ICommandSource source = sender as ICommandSource;
            if (source.CommandParameter is string)
            {
                eStyle style = (eStyle)Enum.Parse(typeof(eStyle), source.CommandParameter.ToString());
                // Using StyleManager change the style and color tinting
                if (StyleManager.IsMetro(style))
                {
                    // More customization is needed for Metro
                    // Capitalize App Button and tab
                    buttonFile.Text = buttonFile.Text.ToUpper();
                    foreach (BaseItem item in RibbonControl.Items)
                    {
                        // Ribbon Control may contain items other than tabs so that needs to be taken in account
                        RibbonTabItem tab = item as RibbonTabItem;
                        if (tab != null)
                            tab.Text = tab.Text.ToUpper();
                    }

                    buttonFile.BackstageTabEnabled = true; // Use Backstage for Metro

                    if (style == eStyle.Metro)
                        StyleManager.MetroColorGeneratorParameters = DevComponents.DotNetBar.Metro.ColorTables.MetroColorGeneratorParameters.DarkBlue;

                    StyleManager.Style = style; // BOOM
                }
                else
                {
                    // If previous style was Metro we need to update other properties as well
                    if (StyleManager.IsMetro(StyleManager.Style))
                    {
                        // Fix capitalization App Button and tab
                        foreach (BaseItem item in RibbonControl.Items)
                        {
                            // Ribbon Control may contain items other than tabs so that needs to be taken in account
                            RibbonTabItem tab = item as RibbonTabItem;
                        }
                    }
                    // Adjust tab strip style
                    StyleManager.ChangeStyle(style, Color.Empty);
                    if (style == eStyle.Office2007Black || style == eStyle.Office2007Blue || style == eStyle.Office2007Silver || style == eStyle.Office2007VistaGlass)
                        buttonFile.BackstageTabEnabled = false;
                    else
                        buttonFile.BackstageTabEnabled = true;
                }
            }
            else if (source.CommandParameter is Color)
            {
                if (StyleManager.IsMetro(StyleManager.Style))
                    StyleManager.MetroColorGeneratorParameters = new DevComponents.DotNetBar.Metro.ColorTables.MetroColorGeneratorParameters(Color.White, (Color)source.CommandParameter);
                else
                    StyleManager.ColorTint = (Color)source.CommandParameter;
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            LoadAllForm();

        }

        private void LoadAllForm()
        {
            var fileMenuCommand2Items = new Dictionary<string, ButtonItem>();
            foreach(var item in menuFileItems.SubItems)
            {
                var buttonItem = item as ButtonItem;
                if(!string.IsNullOrEmpty(buttonItem?.CommandParameter?.ToString())){
                    fileMenuCommand2Items[buttonItem.CommandParameter.ToString()] = buttonItem;
                }
            }

            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            var directory = System.IO.Directory.GetCurrentDirectory();
            foreach (var file in Directory.EnumerateFiles(Path.Combine(directory, "plugins"), "*.UI.*.dll"))
            {
                try
                {
                    var assembly = Assembly.LoadFile(file);
                    foreach(var type in assembly.GetTypes())
                    {
                        if (!type.IsSubclassOf(typeof(SharpErp.UI.Common.BaseTabForm)) && !type.IsSubclassOf(typeof(BaseDialogForm))) continue;
                        ButtonItem fileButtonItem = null, menuButtonItem = null;
                        Console.WriteLine(type.FullName);
                        var attribute = type.GetCustomAttribute<MenuAttribute>();
                        if (attribute == null && type.IsSubclassOf(typeof(BaseDialogForm))) continue;
                        Debug.Assert(attribute != null, "attribute != null");
                        _mapName2FormTypes[type.FullName] = new Tuple<MenuAttribute, Type>(attribute, type);

                        //file menu.
                        if (fileMenuCommand2Items.ContainsKey(type.FullName)) fileButtonItem = fileMenuCommand2Items[type.FullName];
                        else
                        {
                            fileButtonItem = new ButtonItem(type.FullName, attribute?.MenuName)
                            {
                                BeginGroup = true,
                                ButtonStyle = DevComponents.DotNetBar.eButtonStyle.ImageAndText,
                                Image = ((System.Drawing.Image) (resources.GetObject(string.IsNullOrEmpty(attribute.IconName)? "buttonItemBusinessOrder.Image" : attribute.IconName))),
                                SubItemsExpandWidth = 24,
                                CommandParameter = type.FullName
                            };
                            this.menuFileItems.SubItems.Add(fileButtonItem);
                        }
                        fileButtonItem.Click += ButtonItem_Click;

                        //normal menu.
                        var rootMenuItem = _menuModule2ButtonItem[attribute.Module];
                        if (rootMenuItem != null)
                        {
                            foreach (var item in rootMenuItem.SubItems)
                            {
                                var buttonItem = item as ButtonItem;
                                if (buttonItem == null) continue;
                                if (!buttonItem.Text.Trim().Equals(attribute.MenuName.Trim())) continue;
                                menuButtonItem = buttonItem;
                                menuButtonItem.CommandParameter = type.FullName;
                                break;
                            }
                            if (menuButtonItem == null)
                            {
                                menuButtonItem = new ButtonItem(type.FullName, attribute?.MenuName)
                                {
                                    BeginGroup = true,
                                    ButtonStyle = DevComponents.DotNetBar.eButtonStyle.ImageAndText,
                                    Image = ((System.Drawing.Image) (resources.GetObject(string.IsNullOrEmpty(attribute.IconName)? "buttonItemBusinessOrder.Image" : attribute.IconName))),
                                    SubItemsExpandWidth = 24,
                                    CommandParameter = type.FullName
                                };
                                rootMenuItem.SubItems.Add(menuButtonItem);
                            }
                            menuButtonItem.Click += ButtonItem_Click;
                        }

                        //bubble bar.
                        var button = new BubbleButton {Image = menuButtonItem == null? fileButtonItem.Image: menuButtonItem.Image};
                        button.ImageLarge = button.Image;
                        button.TagString = type.FullName;
                        button.TooltipText = attribute?.MenuName;
                        button.Click += ButtonOnClick;
                        this.bubbleBarTab1.Buttons.Add(button);
                    }
                }
                catch (Exception ex)
                {
                    SharpErp.Common.Util.Logger.GetLog().Error("init menu error:", ex);
                }
            }
        }

        private void ButtonOnClick(object sender, ClickEventArgs clickEventArgs)
        {
            var button = sender as BubbleButton;
            if (button == null) return;
            var command = button.TagString.ToString();
            ShowSubForm(this._mapName2FormTypes[string.IsNullOrEmpty(command) ? button.Name : command].Item2);
            
        }

        private void ButtonItem_Click(object sender, EventArgs e)
        {
            var buttonItem = sender as ButtonItem;
            if (buttonItem == null) return;
            var command = buttonItem.CommandParameter.ToString();
            ShowSubForm( this._mapName2FormTypes [string.IsNullOrEmpty(command) ? buttonItem.Name : command].Item2);
        }

        private void ShowSubForm(Type t)
        {
            if (t == null) return;
            var form = Activator.CreateInstance(t);
            var tabForm = form as BaseTabForm;
            var dialog = form as BaseDialogForm;
            if(tabForm != null)
            {
                Debug.Assert(tabForm != null, "tabForm != null");
                tabForm.Text = tabForm.TitleText + (this.MdiChildren.Length + 1);
                tabForm.MdiParent = this;
                tabForm.WindowState = FormWindowState.Maximized;
                tabForm.Show();
                tabForm.Update();
            }else if(dialog != null)
            {
                dialog.ShowDialog();
            } 
        }


        private void buttonItemExit_Click(object sender, EventArgs e)
        {
            var confirmDialog = new TaskDialogInfo("信息", eTaskDialogIcon.Exclamation, "确定退出系统吗？", "", eTaskDialogButton.Yes | eTaskDialogButton.No, eTaskDialogButton.No);
            if (TaskDialog.Show(confirmDialog) != eTaskDialogResult.Yes) return;
            this.Hide();
            this.Close();
        }

        private void buttonFile_Click(object sender, EventArgs e)
        {

        }

        private void ckbBubbleBar_CheckedChanged(object sender, EventArgs e)
        {
            this.panelEx1.Visible = this.ckbBubbleBar.Checked;
        }

        private void buttonStyleCustom_SelectedColorChanged(object sender, EventArgs e)
        {
        }
    }
}
